import { ExceptionFilter, Catch, ArgumentsHost, ForbiddenException } from '@nestjs/common'
import { Response } from 'express'
import { BizError } from 'src/typings'
import { HTTPError } from 'got/dist/source'

@Catch()
export class AppExceptionFilter implements ExceptionFilter {
  catch(exception: any, host: ArgumentsHost) {

    const ctx = host.switchToHttp()
    const response = ctx.getResponse<Response>()
    // const request = ctx.getRequest<Request>()

    let res: IErrorRes
    let exceptionType = exception.constructor.name
    if (handlers[exceptionType]) {
      res = handlers[exceptionType](exception, response)
    } else {
      console.log('AppExceptionFilter', exception)
      res = { status: 500, message: '服务器内部错误', data: exception.message }
    }
    let { status, ...error } = res
    response.status(status)
    response.header('Content-Type', 'application/json; charset=utf-8')
    response.send(error)
  }
}

const handlers: {
  [key: string]: (e: Error, res: Response) => IErrorRes
} = {
  'BizError': (e: BizError, res: Response): IErrorRes => {
    return { status: 500, message: e.message }
  },
  'NotFoundException': () => {
    return { status: 404, message: '请求的资源不存在' }
  },
  'ForbiddenException': (e: ForbiddenException) => {
    return { status: 403, message: '拒绝访问' }
  },
  'UnauthorizedException': () => {
    return { status: 401, message: '未登录或授权信息不正确' }
  },
  'HTTPError': (e: HTTPError) => {
    if (e.message.indexOf('Not Found') > -1) {
      return { status: 500, message: '未找到对应的内容' }
    }
    return { status: 500, message: e.message }
  }
}

export interface IErrorRes<T = any> {
  status: number
  code?: string | number
  message: string
  data?: T
}
